package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicPayReturnDAO;
import com.cssy.xxkj.logic.dao.LogicPayReturnItemDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseReturnDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseReturnItemDAO;
import com.cssy.xxkj.logic.entity.LogicPayItemDO;
import com.cssy.xxkj.logic.entity.LogicPayReturnDO;
import com.cssy.xxkj.logic.entity.LogicPayReturnItemDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseReturnDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseReturnItemDO;
import com.cssy.xxkj.logic.service.ILogicPayReturnService;
import com.cssy.xxkj.logic.service.ILogicUtilService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicPayReturnService")
public class LogicPayReturnServiceImpl implements ILogicPayReturnService {
	
	@Resource(name="logicPayReturnDAO")
	private LogicPayReturnDAO logicPayReturnDAO;
	
	@Resource(name="logicPayReturnItemDAO")
	private LogicPayReturnItemDAO logicPayReturnItemDAO;
	
	@Resource(name="logicPurchaseReturnDAO")
	private LogicPurchaseReturnDAO logicPurchaseReturnDAO;
	
	@Resource(name="logicPurchaseReturnItemDAO")
	private LogicPurchaseReturnItemDAO logicPurchaseReturnItemDAO;
	
	@Resource(name="logicUtilService")
    private ILogicUtilService logicUtilService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;

	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicPayReturnDO> list=logicPayReturnDAO.find(scs);
		rs.setRecordCount(logicPayReturnDAO.count(scs));
		rs.setResults(list);
		return rs;
	}
	@Override
	public List<LogicPayReturnItemDO> findItemListByMap(Map<String, Object> paramMap)
			throws SyBaseException{
		return logicPayReturnItemDAO.findListByMap(paramMap);
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicPayReturnDAO.deleteLogicPayReturnDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicPayReturnDO curAP, User user) throws SyBaseException {
		curAP.setBizModifyDate(new Date());
		curAP.setBizModifyName(user.getRealName());
		curAP.setBizVersionMark(curAP.getBizVersion()+1);
		return logicPayReturnDAO.updateLogicPayReturnDO(curAP);
	}

	@Override
	public LogicPayReturnDO save(LogicPayReturnDO curAP, User user)
			throws SyBaseException {
		if(curAP.getBizCreatorDate()==null){
			curAP.setBizCreatorDate(new Date());
		}
		if(StringUtils.isBlank(curAP.getBizCreatorName())){
			curAP.setBizCreatorName(user.getRealName());
		}
		curAP.setBizVersion(Integer.valueOf(1));
        logicPayReturnDAO.insertLogicPayReturnDO(curAP);
		return curAP;
	}

	@Override
	public LogicPayReturnDO findListById(String id) throws SyBaseException {
		return logicPayReturnDAO.findLogicPayReturnDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicPayReturnDAO.deleteBizRemoved(id);
	}
	
	@Override
	public void payReturnSave(LogicPayReturnDO curAP, HttpServletRequest request)throws SyBaseException{
		String payrDate = request.getParameter("zd014ReturnDate");
		if(StringUtils.isNotBlank(payrDate)){
			curAP.setZd014ReturnDate(DateUtils.stringToDate(payrDate));
		}else{
			curAP.setZd014ReturnDate(new Date());
		}
		String itemdata = request.getParameter("itemdata");
		String itemdelete = request.getParameter("itemdelete");//删除
		try {
			//默认是未退款状态
			curAP.setZd003ReturnStatus(BillStatusUtil.PAYRN_MONEY_BILL_STATUS_ONE);
			String payRnId = "";
			String payRnCode = "";
 			if(curAP==null || StringUtils.isBlank(curAP.getId())){
 				//新增
 				payRnId = IDCodeTypeUtil.getId();
 				payRnCode = syCodeService.getCode(BillTypeConstant.PAYRN,
						BillTypeConstant.PAYRN, SyCode.DATE_YYMM, 5);
 				curAP.setId(payRnId);
 				curAP.setZd001Code(payRnCode);
 				this.save(curAP, SessionUtil.getUser(request));
 			}else{
 				//修改
 				Integer row = this.update(curAP, SessionUtil.getUser(request));
 				if(row==null||row.intValue()==0){
 					throw new SyBaseException("数据发生错误，请重新提交。");
 				}else{
 					if(StringUtils.isNotBlank(itemdelete)){
 						List<LogicPayReturnItemDO> pmList = JSONArray.parseArray(itemdelete, LogicPayReturnItemDO.class);
 						for(LogicPayReturnItemDO payRnItem : pmList){
 							if(payRnItem==null || StringUtils.isBlank(payRnItem.getId())){
 								continue;
 							}
 							logicPayReturnItemDAO.deleteLogicPayReturnItemDOByPrimaryKey(payRnItem.getId());
 						}
 					}
 				}
 			}
 			//收款行记录表
 			List<LogicPayReturnItemDO> payRnItemList = JSONArray.parseArray(itemdata, LogicPayReturnItemDO.class);
 			for(LogicPayReturnItemDO payRnItem : payRnItemList){
 				if(payRnItem==null){
 					continue;
 				}
 				if(StringUtils.isBlank(payRnItem.getId())){
 					//新增
 					payRnItem.setId(IDCodeTypeUtil.getId());
 					payRnItem.setZd001ReturnId(payRnId);
 					payRnItem.setZd001ReturnCode(payRnCode);
 					logicPayReturnItemDAO.insertLogicPayReturnItemDO(payRnItem);
 				}else{
 					logicPayReturnItemDAO.updateLogicPayReturnItemDO(payRnItem);
 				}
 			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	@Override
	public void payReturnCommit(LogicPayReturnDO curAP, HttpServletRequest request)throws SyBaseException{
		try {
			String payrDate = request.getParameter("zd014ReturnDate");
			if(StringUtils.isNotBlank(payrDate)){
				curAP.setZd014ReturnDate(DateUtils.stringToDate(payrDate));
			}else{
				curAP.setZd014ReturnDate(new Date());
			}
			String itemdata = request.getParameter("itemdata");
			String itemdelete = request.getParameter("itemdelete");//删除
			//不提交的退款
			if(StringUtils.isNotBlank(itemdelete)){
				List<LogicPayReturnItemDO> pmrList = JSONArray.parseArray(itemdelete, LogicPayReturnItemDO.class);
				for(LogicPayReturnItemDO payRnItem : pmrList){
					if(payRnItem==null || StringUtils.isBlank(payRnItem.getId())){
						continue;
					}
					logicPayReturnItemDAO.deleteLogicPayReturnItemDOByPrimaryKey(payRnItem.getId());
				}
			}
			//提交的退款
			List<LogicPayReturnItemDO> payRnItemList = JSONArray.parseArray(itemdata, LogicPayReturnItemDO.class);
			
			Map<String, BigDecimal> payHasMap = this.findHasPayRetrunQueryToMap(curAP.getZd002PcsrId());
			Map<String, LogicPurchaseReturnItemDO> pcsrmItemMap = this.findQueryPcsrToMap(curAP.getZd002PcsrId());
			for(LogicPayReturnItemDO payRnItem : payRnItemList){
				if(payRnItem == null){
					continue;
				}
				String keyStr = curAP.getZd002PcsrId()+"_"+payRnItem.getZd002MaterId();
				//应付总金额
				BigDecimal zdSmMoney = payRnItem.getZd016Amount()==null?BigDecimal.ZERO:payRnItem.getZd016Amount();
				//本次付款金额
				BigDecimal zdThMoney = payRnItem.getZd018TheAmount()==null?BigDecimal.ZERO:payRnItem.getZd018TheAmount();
				//当前付款总金额
				BigDecimal zdThSmMoney = BigDecimal.ZERO;
				if(payHasMap==null||payHasMap.get(keyStr)==null){
					zdThSmMoney = zdThMoney;
				}else{
					BigDecimal zdExMoney = payHasMap.get(keyStr);
					zdThSmMoney = zdThMoney.add(zdExMoney);
				}
				//comMoney = 应付总金额-当前总金额
				BigDecimal comMoney = zdSmMoney.subtract(zdThSmMoney);
				int compSt = BigDecimal.ZERO.compareTo(comMoney);
				if(compSt==1){
					throw new SyBaseException("本次付款的金额大于应付金额，请检查。");
				}else{
					if(payHasMap==null){
						payHasMap = new HashMap<String, BigDecimal>();
					}
					payHasMap.put(keyStr, zdThSmMoney);
				}
			}
			LogicPurchaseReturnDO pcsr = this.findPurchaseReturn(curAP.getZd002PcsrId());
			boolean canUpSt = false;
			if(pcsrmItemMap==null){
				throw new SyBaseException("没有查询到采购入库单的物料集合。");
			}else{
				for(LogicPurchaseReturnItemDO pcsrmItem : pcsrmItemMap.values()){
					if(pcsrmItem==null){
						continue;
					}
					String keyStr = curAP.getZd002PcsrId()+"_"+pcsrmItem.getZd003MaterId();
					if(payHasMap.get(keyStr)==null){
						canUpSt = false;
					}else{
						//已付款数
						BigDecimal tempMoney = payHasMap.get(keyStr);
						BigDecimal zdQuantity = pcsrmItem.getZd020BackQuantity()==null?BigDecimal.ZERO:pcsrmItem.getZd020BackQuantity();
						BigDecimal zdTaxprice = pcsrmItem.getZd013TaxPrice()==null?BigDecimal.ZERO:pcsrmItem.getZd013TaxPrice();
						//应付款数
						BigDecimal zdHasMoney = zdQuantity.multiply(zdTaxprice);
						//本次
						//减去数量
						BigDecimal upMoney = zdHasMoney.subtract(tempMoney);
						int upComp = BigDecimal.ZERO.compareTo(upMoney);
						if(upComp==1){
							throw new SyBaseException("付款总额大于应付款。");
						}
						if(upComp==0){
							canUpSt = true;
						}
						if(upComp==-1){
							canUpSt = false;
						}
					}
				}
			}
			
			if(canUpSt){
				//完全付款
				pcsr.setZd006PayStatus(BillStatusUtil.PCSR_PAY_BILL_STATUS_TWO);
			}else{
				//部分付款
				pcsr.setZd006PayStatus(BillStatusUtil.PCSR_PAY_BILL_STATUS_THREE);
			}
			logicPurchaseReturnDAO.updateLogicPurchaseReturnDO(pcsr);
			
			this.update(curAP, SessionUtil.getUser(request));
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	private Map<String, BigDecimal> findHasPayRetrunQueryToMap(String pcsrId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcsrId", pcsrId);
		paramMap.put("zdStatus", BillStatusUtil.PAYRN_BILL_STATUS_TWO);
		List<LogicPayReturnItemDO> payRnItemList =  logicPayReturnItemDAO.findListByMap(paramMap);
		if(payRnItemList==null||payRnItemList.isEmpty()||payRnItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> payRnHasMap = new HashMap<String, BigDecimal>();
			for(LogicPayReturnItemDO payRnItem : payRnItemList){
				if(payRnItem==null){
					continue;
				}
				String keyStr = pcsrId+"_"+payRnItem.getZd002MaterId();
				BigDecimal theMoney = payRnItem.getZd018TheAmount()==null?BigDecimal.ONE:payRnItem.getZd018TheAmount();
				if(payRnHasMap.get(keyStr)==null){
					payRnHasMap.put(keyStr, theMoney);
				}else{
					payRnHasMap.put(keyStr, theMoney.add(payRnHasMap.get(keyStr)));
				}
			}
			return payRnHasMap;
		}
	}
	
	private Map<String, LogicPurchaseReturnItemDO> findQueryPcsrToMap(String pcsrId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcsrId", pcsrId);
		List<LogicPurchaseReturnItemDO> pcsrmList = logicPurchaseReturnItemDAO.findListByMap(paramMap);
		if(pcsrmList==null||pcsrmList.isEmpty()||pcsrmList.size()==0){
			return null;
		}else{
			Map<String, LogicPurchaseReturnItemDO> pcswmMap = new HashMap<String, LogicPurchaseReturnItemDO>();
			for(LogicPurchaseReturnItemDO pcsrm : pcsrmList){
				if(pcsrm==null){
					continue;
				}
				String keyStr = pcsrId+"_"+pcsrm.getZd003MaterId();
				pcswmMap.put(keyStr, pcsrm);
			}
			return pcswmMap;
		}
	}
	
	/**
	 * 
	 * @param pcsrId
	 * @return
	 */
	private LogicPurchaseReturnDO findPurchaseReturn(String pcsrId){
		LogicPurchaseReturnDO pcsr = null;
		SearchConditions pcsrScs = new SearchConditions();
		pcsrScs.addCondition("id", pcsrId, SearchCondition.OP_EQUAL);
		List<LogicPurchaseReturnDO> pcsrList = logicUtilService.resultPurchaseReturn(pcsrScs);
		if(pcsrList==null||pcsrList.isEmpty()||pcsrList.size()==0){
			throw new SyBaseException("");
		}else{
			pcsr = pcsrList.get(0);
		}
		return pcsr;
	}
	
	public BigDecimal findQueryHasPayReturnMoney(Map<String, Object> paramMap)throws SyBaseException{
		try{
			List<LogicPayReturnItemDO> payRnItemList = logicPayReturnItemDAO.findListByMap(paramMap);
			if(payRnItemList==null||payRnItemList.isEmpty()||payRnItemList.size()==0){
				return BigDecimal.ZERO;
			}else{
				BigDecimal hasSumMoney = BigDecimal.ZERO;
				for(LogicPayReturnItemDO payRnItem : payRnItemList){
					if(payRnItem==null){
						continue;
					}
					BigDecimal theMoney = payRnItem.getZd018TheAmount()==null?BigDecimal.ZERO:payRnItem.getZd018TheAmount();
					hasSumMoney = hasSumMoney.add(theMoney);
				}
				return hasSumMoney;
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}

}
